/*
 * =====================================================================================
 *
 *       Filename:  listAllWord.cpp
 *
 *    Description:
 *
 *        Version:  1.0
 *        Created:  2017年04月14日 12时04分32秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Crane (), wanghe@galaxyeye-tech.com
 *   Organization:  Galaxy-eye
 *
 * =====================================================================================
 */

Dict  dict;       // 词典类: 内部维护所有词汇, 和基本的词汇操作等...

typedef  std::shared_ptr<SegTreeNode>  SegTree;     // SegTreeNode 指针类型表示SegTree: 拭目以待
typedef  SegTreeNode  * SegTree;     // SegTreeNode 指针类型表示SegTree: 拭目以待

class SegTreeNode      // 分词树上的一个节点
{
    string  m_myWord;                 // 字节点自身维护的一个词
    vector<SegTree>   m_children;    // 子节点们都是树
}


// 将索引和树的映射存储起来: 使用stl的map, 或者自己使用数组, hash等实现. 逻辑上是一个map
// tip: 因为c++ 中的指针是一个 机器位的整型, 所以是可以建立索引的.
Map<int processIndex, SegTree tree>  g_segTreeMap;      // 存储索引和树的结果.


// 供外部: 获取分词树.
SegTree getSegTree(string  sentence)
{
    return getSegTree(sentence, 0);
}

// 参数 fromIndex: 从fromIndex开始处理. 也可以命名为 processFrom
SegTree  getSegTree(string sentence, int fromIndex)
{
    // 如果sentence已经没有字符可处理了了, 返回空.
    if( fromIndex != sentence.end()  )
        return NULL;

    // 性能提升的关键!!!  ( 动态规划的思想 ).
    // 因为这里关于( index + SegTree ) 的映射返回, 可能导致多个地方引用fromIndex关联的树.
    // 如果引起析构不便. 可以使用智能指针 shared_ptr 表示SegTree类型.
    if( g_segTreeMap.hasProcessed(fromIndex) )       // 如果已经处理过fromIndex开始的sentence, 直接返回已经存储起来的树.
        return g_segTreeMap(fromIndex);

    SegTree    l_top;
    wordBegin = 0;

    // 循环获取词汇进行分析
    for wordLen = (from 1 to  MaxWordLength)      // 从0 到最长词汇长度: 假设为5进行分析
    {
        SegTree l_child;                // 子节点的树.

        // 先获取一个词, 未必是一个存在于字典中的合法词汇, 叫做伪词好了
        toIndex = fromIndex + wordLen;
        tmpWord = sentence[fromIndex: toIndex];

        if( ! dict.isWord(tmpWord) )      // 判断伪词是否是 一个真正的词. 如果不是直接退出开始下一轮循环
            continue;

        l_child.m_myWord = tmpWord;        // 字节点自身维护的一个词.

        l_child.m_children = getSegTree(sentence, toIndex);       // 为子节点构造自己的分词树.

        // 构造完子节点树后: 建立树和索引toIndex之间的映射.
        g_segTreeMap[toIndex] = l_child.m_chidren;

        // 为l_top 添加一个字节点.
        l_top.m_children.append( l_child );
    }

    return l_top;
}
